#ifndef __AUDIO_H__
#define __AUDIO_H__
#include "osal.h"
#include "audio_num.h"
#include "diy_audio.h"


/* 语言类型 */                     
#define LANGUAGE_CHINESE           0  //中文
#define LANGUAGE_ENGLISH           1  //英文
#define LANGUAGE_SPANISH           2  //西班牙
#define LANGUAGE_FRENCH            3  //法语
#define LANGUAGE_PORTUGUESE        4  //葡萄牙
#define LANGUAGE_RUSSIAN           5  //俄语
#define LANGUAGE_ARAB              6  //阿拉伯
#define LANGUAGE_THAILAND          7  //泰国
#define LANGUAGE_VIETNAM           8  //越南
#define LANGUAGE_INDONESIA         9  //印尼
#define LANGUAGE_KAZAK         	   10  //哈萨克 

#define LANGUAGE_LAST_ONE          11 //最后一个

/* 语言对应的各国简写,json上报/设置时用到. 必须按照上面语言的顺序 */
#define LANGUAGE_STRING { "zh", "en", "es", "fr", "pt", "ru", "sa", "th", "vn", "id", "kk"}

/* 语音类型 */                     
#define AUDIO_MUTE                 1  //静音
#define AUDIO_NORMAL               0  //普通语音模式


/* 语音PUBLISH消息（COMP->APP） */
typedef struct
{
    uint16_t number;
}AudioPublishMsg_t;

/* 语音组件开放的NV数据 */
typedef struct
{
    uint8_t nvInitFlag;
    uint8_t language;
    uint8_t volume;
    uint8_t mute;
    uint8_t version[8];
}AuidoNv_stu_t;

/* 语音组件昵称枚举 */
typedef enum
{
    AUDIO_ALIAS_FRONT = 1, //前板语音组件（真人语音）
    AUDIO_ALIAS_REAR  = 2, //后板语音组件（门铃播放）
}AuidoAlias_enum_t;


/* 获取当前语言 */
#define Audio_GetLanguage()                                  \
({                                                           \
    uint8_t temp;                                            \
    (OSAL_NvReadGlobal(COMP_AUDIO,                           \
                       AUDIO_ALIAS_FRONT,                    \
                       OSAL_OFFSET(AuidoNv_stu_t, language), \
                       &temp,                                \
                       sizeof(temp)) != ERROR) ? temp : 0;   \
})

/* 获取当前音量 */
#define Audio_GetVolume()                                         \
({                                                                \
    uint8_t temp;                                                 \
    (OSAL_NvReadGlobal(COMP_AUDIO,                                \
                       AUDIO_ALIAS_FRONT,                         \
                       OSAL_OFFSET(AuidoNv_stu_t, volume),        \
                       &temp, sizeof(temp)) != ERROR) ? temp : 0; \
})

/* 获取当前静音状态 */
#define Audio_GetMuteMode()                                       \
({                                                                \
    uint8_t temp;                                                 \
    (OSAL_NvReadGlobal(COMP_AUDIO,                                \
                       AUDIO_ALIAS_FRONT,                         \
                       OSAL_OFFSET(AuidoNv_stu_t, mute),          \
                       &temp, sizeof(temp)) != ERROR) ? temp : 0; \
})

/* 获取语音固件版本 */
#define Audio_GetVersion(ver)                               \
({                                                          \
    (OSAL_NvReadGlobal(COMP_AUDIO,                          \
                       AUDIO_ALIAS_FRONT,                   \
                       OSAL_OFFSET(AuidoNv_stu_t, version), \
                       ver, 8) != ERROR) ? SUCCESS : ERROR; \
})




/* 语音组件邮箱主题（APP->COMP） */
#define AUDIO_MBOX_PLAY          0
#define AUDIO_MBOX_PLAYSTR       1
#define AUDIO_MBOX_SET_LAN       2
#define AUDIO_MBOX_SET_VOL       3
#define AUDIO_MBOX_SET_MUTE      4
#define AUDIO_MBOX_TITLE_DIY     5
#define AUDIO_MBOX_SEND_DIY      6
#define AUDIO_MBOX_DEL_DIY       7
#define AUDIO_MBOX_NOT_MUTE      8
/* 禁止静音的场景事件 */
typedef enum {
    ENTER_MANAGE_NOMUTE_FLAG        = 0x01,     /* 进入管理模式 */
    ENTER_CONFIG_NET_NOMUTE_FLAG    = 0x02,     /* 进入配网模式 */
}NoMute_Flag_enum_t;

/* 播放门铃声（opt: 1立即播   2空闲才播   其它：排队播） */
#define Audio_PlayDoorbell(sn, opt)                                  \
({                                                                   \
    uint8_t temp[4] = {AUDIO_MBOX_PLAY, opt};                        \
    uint16_t num = sn;                                               \
    OSAL_LOG("Audio_PlayDoorbell\r\n");                              \
    memcpy(&temp[2], &num, sizeof(num));                             \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_REAR, temp, sizeof(temp)); \
})

/* 播放一句语音（opt: 1立即播   2空闲才播   其它：排队播） */
#define Audio_Play(sn, opt)                                           \
({                                                                    \
    uint8_t temp[4] = {AUDIO_MBOX_PLAY, opt};                         \
    uint16_t num = sn;                                                \
    OSAL_LOG("Audio_Play: %d\r\n", sn);                               \
    memcpy(&temp[2], &num, sizeof(num));                              \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp)); \
})

/* 播放一句字符串 */
#define Audio_PlayString(str)                                          \
({                                                                     \
    uint8_t temp[36] = {AUDIO_MBOX_PLAYSTR};                           \
    OSAL_LOG("Audio_PlayString: %s\r\n", str);                         \
    strcpy((char*)&temp[1], str);                                      \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp));  \
})

/* 设置语言 */
#define Audio_SetLanguage(lan)                                         \
({                                                                     \
    uint8_t temp[2] = {AUDIO_MBOX_SET_LAN, lan};                       \
    OSAL_LOG("Audio_SetLanguage: %d\r\n", lan);                        \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp));  \
})

/* 设置音量 */
#define Audio_SetVolume(vol)                                           \
({                                                                     \
    uint8_t temp[2] = {AUDIO_MBOX_SET_VOL, vol};                       \
    OSAL_LOG("Audio_SetVolume: %d\r\n", vol);                          \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp));  \
})

/* 设置静音模式 */
#define Audio_SetMuteMode(mute)                                        \
({                                                                     \
    uint8_t temp[2] = {AUDIO_MBOX_SET_MUTE, mute};                     \
    OSAL_LOG("Audio_SetMuteMode: %d\r\n", mute);                       \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp));  \
})

/* 
 * 下发个性化语音信息（发送完最后一包数据后调用）
 * _sn: 个性化语音编号，参考audio_num.h
 * _total_len: 个性化语音数据总大小
 * _md5: MD5值
 */
#define Audio_TitleDIYAudio(_sn, _total_len, _md5)                                          \
({                                                                                          \
    uint8_t *temp = (uint8_t *)OSAL_Malloc(sizeof(titleAudioMsg_stu_t) + 1);                \
    titleAudioMsg_stu_t* pData = (titleAudioMsg_stu_t*)&temp[1];                            \
    temp[0] = AUDIO_MBOX_TITLE_DIY;                                                         \
    pData->SN = (uint16_t)_sn;                                                              \
    pData->total_len = (uint32_t)_total_len;                                                \
    strcpy(pData->md5, _md5);                                                               \
    OSAL_LOG("SN:%d, total: 0x%X\r\n", pData->SN, pData->total_len);                        \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, (sizeof(titleAudioMsg_stu_t) + 1));  \
    OSAL_Free(temp);                                                                        \
})

/* 
 * 分包发送个性化语音数据 
 * _offect: 地址偏移(首包从0开始)
 * _pack_len: 单包长度，默认1024，最后一包<1024
 * _data: 数据
 */
#define Audio_SendDIYAudio(_offect, _pack_len, _data)                            \
({                                                                               \
    uint8_t *temp = (uint8_t *)OSAL_Malloc(6 + _pack_len + 1);                   \
    sendAudioMsg_stu_t* pData = (sendAudioMsg_stu_t*)&temp[1];                   \
    temp[0] = AUDIO_MBOX_SEND_DIY;                                               \
    pData->addr_offect = (uint32_t)_offect;                                      \
    pData->pack_len = (uint16_t)_pack_len;                                       \
    memcpy(pData->data, _data, _pack_len);                                       \
    OSAL_LOG("offect: 0x%X, pack:0x%X\r\n", pData->addr_offect, pData->pack_len);\
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, (7 + _pack_len));         \
    OSAL_Free(temp);                                                             \
})

/* 删除个性化语音 */
#define Audio_DeletDIYAudio(_sn)                                       \
({                                                                     \
    uint8_t temp[3] = {AUDIO_MBOX_DEL_DIY};                            \
    uint16_t num = _sn;                                                \
    OSAL_LOG("Audio_Del: %d\r\n", _sn);                                \
    memcpy(&temp[1], &num, sizeof(num));                               \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp));  \
})

/**
  * @brief  设置语音禁止静音标志
  * @note
  * @param  flag：NoMute_Flag_enum_t 事件标记
  * @param  opt：1：相应标志置起 0：清除相对应标记
  */
#define Audio_SetNotMute(flag,opt)                                      \
({                                                                      \
    uint8_t temp[3] = {0};                                              \
    temp[0] = AUDIO_MBOX_NOT_MUTE;                                      \
    temp[1] = opt;                                                      \
    temp[2] = flag;                                                     \
    OSAL_LOG("Audio set mute flag: 0x%02X\r\n",flag);                   \
    OSAL_MboxPost(COMP_AUDIO, AUDIO_ALIAS_FRONT, temp, sizeof(temp));   \
})


#endif /* __AUDIO_H__ */

